import fs from 'fs';

export interface DBMailInfo {
    mailId: number,
    uid: string,
    from: string,
    time: number,
    title: string,
    content: string,
    state: string,
}

let mailIdBase = 1000;

let dbData: { [key: string]: DBMailInfo } = {};
let uid2Mail: { [key: string]: DBMailInfo[] } = {};
const dbFile = './db_mail.json';

if (fs.existsSync(dbFile)) {
    let f = fs.readFileSync(dbFile, { encoding: 'utf-8', flag: 'r' });
    if (f) {
        let str = f.toString();
        dbData = JSON.parse(str);
    }
}

Object.keys(dbData).forEach((key) => {
    let mailInfo = dbData[key];
    if (mailInfo.state == 'deleted') {
        delete dbData[key];
        return;
    }
    if (!uid2Mail[mailInfo.uid]) {
        uid2Mail[mailInfo.uid] = [];
    }
    uid2Mail[mailInfo.uid].push(mailInfo);
    if (mailInfo.mailId >= mailIdBase) {
        mailIdBase = mailInfo.mailId + 1;
    }
});

function flushDB() {
    fs.writeFileSync(dbFile, JSON.stringify(dbData));
}

export class DBMail {

    private static geMailInfo(mailId: number) {
        return dbData[mailId];
    }

    public static insterNewMail(from: string, to: string, title: string, content: string) {
        let mailInfo = {
            mailId: mailIdBase++,
            uid: to,
            from: from,
            time: Date.now(),
            title: title,
            content: content,
            state: '',
        };

        dbData[mailInfo.mailId] = mailInfo;
        if (!uid2Mail[mailInfo.uid]) {
            uid2Mail[mailInfo.uid] = [];
        }
        uid2Mail[mailInfo.uid].push(mailInfo);
        flushDB();
    }

    public static deleteMail(mailId: number) {
        let mailInfo = dbData[mailId];
        if (mailInfo) {
            mailInfo.state = 'deleted';
            let arr = this.getMailsByUid(mailInfo.uid);
            let index = arr.indexOf(mailInfo);
            if (index != -1) {
                arr.splice(index, 1);
            }
            delete dbData[mailId];
        }
        flushDB();
    }

    public static getMailsByUid(uid: string) {
        let mails = uid2Mail[uid] || [];
        return mails;
    }

    public static markAsRead(mailId: number) {
        let mailInfo = dbData[mailId];
        if (mailInfo) {
            mailInfo.state = 'read';
        }
        flushDB();
    }

    public static markAllAsRead(uid: string) {

        let mails = uid2Mail[uid];
        if (mails) {
            mails.forEach(v => {
                v.state = 'read';
            });
        }
        flushDB();
    }

    public static clearMailsByUid(uid: string) {

        uid2Mail[uid] = [];
        flushDB();
    }
}